package com.start.form.engine.core.global;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.start.common.exceptions.StartBusException;
import com.start.common.std.StartBaseSingleton;
import com.start.common.std.StartSingletonFactory;
import com.start.form.engine.core.StartColumnInfo;
import com.start.form.engine.core.StartFormEngineConstant;
import com.start.form.engine.core.model.StartFormColumnModel;
import com.start.form.engine.core.entity.StartFormConfig;
import com.start.form.engine.core.listener.StartTableListener;
import com.start.form.engine.core.tools.StartAvueColTools;
import com.start.form.engine.core.tools.StartTableOptionTools;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

@Slf4j
public class StartGlobalTableListener extends StartBaseSingleton<StartGlobalTableListener> implements StartTableListener, StartFormEngineConstant.FormBaseColumns {

    private DispatcherStartFormListener dispatcher;

    private static final Pattern TABLE_NAME_VALIDATE = Pattern.compile("^[a-zA-Z]{1}(_|-|[A-zA-z]|\\d){0,100}$");

    public static StartGlobalTableListener getInstance() {
        return StartSingletonFactory.get(StartGlobalTableListener.class);
    }

    /**
     * 调用初始化函数
     */
    @Override
    public void init() {
        dispatcher = StartSingletonFactory.get(DispatcherStartFormListener.class);
    }


    /**
     * 创建数据表前
     *
     * @param formConfig
     */
    @Override
    public void beforeCreateTable(StartFormConfig formConfig) {
        checkStarFormConfig(formConfig);
        JSONArray column = StartTableOptionTools.getColumn(formConfig);
        autoAppendDefaultField(column);
        dispatcher.beforeCreateTable(formConfig);
        log.error("开始创建数据表：{}", formConfig.getTableName());
    }

    private void checkStarFormConfig(StartFormConfig formConfig) {
        if (StringUtils.isAllBlank(formConfig.getName())) throw new StartBusException("请输入表单中文名称");
        if (StringUtils.isAllBlank(formConfig.getTableName())) throw new StartBusException("请输入表单英文名称");
        if (formConfig.getTableName().length() > 99) {
            throw new StartBusException("数据表名长度不能大于100");
        }
        if (!TABLE_NAME_VALIDATE.matcher(formConfig.getTableName()).find()) {
            throw new StartBusException("数据表名只能是英文字母开头+数字或者+下划线或者加横线");
        }
    }

    /**
     * 主表追加默认字段
     *
     * @param column
     */
    private void autoAppendDefaultField(JSONArray column) {
        Map<String, Integer> columnsMap = StartTableOptionTools.getTableOptionFieldIndex(column);
        handlerAvueDynamicDefaultField(column);
        StartAvueColTools.autoAppendGlobalField(columnsMap, column);
    }

    /**
     * 处理子表单字段追加
     *
     * @param column
     */
    private void handlerAvueDynamicDefaultField(JSONArray column) {
        for (int i = 0; i < column.size(); i++) {
            JSONObject dynamic = column.getJSONObject(i);
            if (!"dynamic".equals(dynamic.getString("type"))) {
                continue;
            }
            JSONObject children = dynamic.getJSONObject("children");
            JSONArray dynamicColumns = children.getJSONArray("column");
            Map<String, Integer> dynamicColumnsMap = StartTableOptionTools.getTableOptionFieldIndex(dynamicColumns);
            StartAvueColTools.autoAppendGlobalField(dynamicColumnsMap, dynamicColumns);
            StartAvueColTools.autoAppendField(dynamicColumnsMap, dynamicColumns, COLUMN_MAIN_TABLE_ID, "主表id", "varchar", 32, 1);
        }
    }

    /**
     * 修改数据表后
     *
     * @param formConfig
     */
    @Override
    public void afterCreateTable(StartFormConfig formConfig) {
        dispatcher.afterCreateTable(formConfig);
        log.info("数据表{}创建成功，但未同步到数据库", formConfig.getTableName());
    }

    @Override
    public void beforeUpdateTable(StartFormConfig formConfig, List<StartFormColumnModel> oldColumn) {
        checkStarFormConfig(formConfig);
        JSONArray column = StartTableOptionTools.getColumn(formConfig);
        autoAppendDefaultField(column);
        dispatcher.beforeUpdateTable(formConfig, oldColumn);
    }

    @Override
    public void afterUpdateTable(StartFormConfig formConfig) {
        dispatcher.afterUpdateTable(formConfig);
    }

    @Override
    public void beforeSynchronizationTable(StartFormConfig formConfig, StartColumnInfo startColumnInfo) {
        dispatcher.beforeSynchronizationTable(formConfig, startColumnInfo);
        log.info("开始同步数据表结构到数据库：{}", formConfig.getTableName());
    }

    @Override
    public void afterSynchronizationTable(StartFormConfig formConfig, List<StartFormColumnModel> newColumn, StartColumnInfo startColumnInfo) {
        dispatcher.afterSynchronizationTable(formConfig, newColumn, startColumnInfo);
        log.info("数据表结构同步到数据库成功：{}", formConfig.getTableName());
    }

    /**
     * 删除数据表之前
     *
     * @param formConfig
     */
    @Override
    public void beforeDeleteTable(StartFormConfig formConfig) {
        dispatcher.beforeDeleteTable(formConfig);
        log.warn("开始删除数据表：{}", formConfig.getTableName());
    }

    /**
     * 删除数据表之后
     *
     * @param formConfig
     */
    @Override
    public void afterDeleteTable(StartFormConfig formConfig) {
        dispatcher.afterDeleteTable(formConfig);
        log.warn("数据表删除成功：{}", formConfig.getTableName());
    }

    /**
     * 清空数据表前
     *
     * @param formConfig
     */
    @Override
    public void beforeClearData(StartFormConfig formConfig) {
        dispatcher.beforeClearData(formConfig);
        log.warn("开始清空数据表数据：{}", formConfig.getTableName());
    }

    /**
     * 清口数据表后
     *
     * @param formConfig
     */
    @Override
    public void afterClearData(StartFormConfig formConfig) {
        dispatcher.afterClearData(formConfig);
        log.warn("数据表数据清空成功：{}", formConfig.getTableName());
    }


}
